package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.sys.modules.models.SysParam;
import cn.wizzer.app.sys.modules.services.SysParamService;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.UserRestriction;
import cn.wizzer.app.user.modules.models.enums.BizTypeEnum;
import cn.wizzer.app.user.modules.models.vo.UserRestrictionVo;
import cn.wizzer.app.user.modules.services.UserAgentService;
import cn.wizzer.app.user.modules.services.UserRestrictionService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.user.modules.services.account.UserAccountRecordService;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Map;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = UserAgentService.class)
public class UserAgentServiceImpl extends BaseServiceImpl<User> implements UserAgentService {
    public UserAgentServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private CommonDBService dbService;

    @Reference
    @Inject
    private SysParamService sysParamService;

    @Inject
    @Reference
    private UserService userService;

    @Inject
    private UserAccountRecordService accountRecordService;

    @Inject
    private UserRestrictionService restrictionService;

    @Override
    public Pagination subUsers(int pageNumber, int pageSize, String appid, String searchKeyword, long startTime, long endTime) {
        Sql sql = Sqls.create("select u.username,u.nickName,u.phone,u.id as uId,u.headPicture,u.ctAt as uCtAt,lastLoginAt,r.* " +
                "from user_restriction r ");
        Sql countSql = Sqls.create("select count(1) from user_restriction r ");
        Sql joinSql = Sqls.create("left join user u on u.id = r.user_id " +
                "$condition ");
        Cnd cnd = Cnd.where("u.inviter", "=", appid);
        if (Strings.isNotBlank(searchKeyword)) {
            searchKeyword = "%" + searchKeyword + "%";
            cnd.and(Cnd.exps("u.nickName", "LIKE", searchKeyword)
                    .or("u.phone", "LIKE", searchKeyword)
                    .or("u.userName", "LIKE", searchKeyword));
        }
        if (0 != startTime) {
            cnd.and("u.ctAt", ">=", startTime);
        }
        if (0 != endTime) {
            cnd.and("u.ctAt", "<=", endTime);
        }
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("order by ctAt desc");
        countSql.appendSourceSql(joinSql.toString());

        SysParam sysParam = sysParamService.fetch();
        Pagination pagination = dbService.listPage(UserRestrictionVo.class, pageNumber, pageSize, sql.toString(), countSql.toString());
        Sql sumSql = Sqls.create("select ifnull(sum(operate_amount), 0) " +
                "from user_account_record " +
                "where biz_type = @bizType " +
                "and user_id = @userId ");
        sumSql.setParam("bizType", BizTypeEnum.SELF_REBATE);
        sumSql.setCallback(Sqls.callback.str());
        for (UserRestrictionVo vo : pagination.getList(UserRestrictionVo.class)) {
            //默认项
            if (Strings.isBlank(vo.getId())) {
                vo.setSelfRate(sysParam.getSelfRate());
                vo.setSuperRate(sysParam.getSuperRate());
            }
            //返水统计
            String fromUser = vo.getUserId();
            //执行求和sql
            sumSql.setParam("userId", fromUser);
            this.dao().execute(sumSql);
            vo.setToSelfCount(new BigDecimal(sumSql.getString()).setScale(2, RoundingMode.DOWN));
            BigDecimal superCount = rebateCount2Super(appid, fromUser);
            vo.setToSuperCount(superCount);
        }
        return pagination;
    }

    /**
     * 统计用户对代理的总返利
     * @param toUser
     * @param fromUser
     * @return
     */
    private BigDecimal rebateCount2Super(String toUser, String fromUser) {
        Sql sql = Sqls.create("select IFNULL(sum(r.operate_amount), 0) " +
                "from user_account_record r " +
                "left join crown_bet_count c on c.id = r.biz_id and biz_type= @bizType " +
                "where r.user_id = @toUser " +
                "and c.userId = @fromUser ");
        sql.setParam("bizType", BizTypeEnum.SUB_REBATE);
        sql.setParam("toUser", toUser);
        sql.setParam("fromUser", fromUser);
        sql.setCallback(Sqls.callback.str());
        this.dao().execute(sql);
        return new BigDecimal(sql.getString()).setScale(2, RoundingMode.DOWN);
    }

    @Override
    public Map inviteCount(String appid) {
        //today 00:00
        long today = Times.ams(Times.nextDay(0)) / 1000;
        //yesterday 00:00
        long yesterday = Times.ams(Times.befoDay()) / 1000;
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DATE, 1);
        instance.set(Calendar.HOUR, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        //this month 1th 00:00
        long thisMonth = instance.getTime().getTime() / 1000;
        instance.add(Calendar.MONTH, -1);
        //last month 1th 00:00
        long lastMonth = instance.getTime().getTime() / 1000;
        //共计
        int all = this.count(Cnd.where("inviter", "=", appid));
        //昨天
        int yesterdayCount = this.count(Cnd.where("inviter", "=", appid)
                .and(new Static("ctAt between " + yesterday + " and " + today)));
        //本月
        int thisMonthCount = this.count(Cnd.where("inviter", "=", appid)
                .and("ctAt", ">=", thisMonth));
        //上个月
        int lastMonthCount = this.count(Cnd.where("inviter", "=", appid)
                .and(new Static("ctAt between " + lastMonth + " and " + thisMonth)));

        return Result.createMap("all", all,
                "yesterday", yesterdayCount,
                "thisMonth", thisMonthCount,
                "lastMonth", lastMonthCount);
    }

    @Override
    public void editRate(String userId, String appid, int selfRate, int superRate) {
        //身份验证
        User fetch = userService.fetch(userId);
        if (fetch == null || !fetch.getInviter().equals(appid)) {
            Result.breakWith("???");
        }
        //返点验证
        double totalRateMax = sysParamService.fetch().getTotalRateMax();
        double selfRateMax = sysParamService.fetch().getSelfRateMax();
        double superRateMax = sysParamService.fetch().getSuperRateMax();
        if (selfRate > selfRateMax) {
            Result.breakWith("个人返点最大值为：" + selfRateMax / 100 + "%");
        } else if (superRate > superRateMax) {
            Result.breakWith("代理返点最大值为：" + superRateMax / 100 + "%");
        } else if ((selfRate + superRate) > totalRateMax) {
            Result.breakWith("总返点最大值为：" + totalRateMax / 100 + "%");
        }
        //缓存中取出用户限制数据
        UserRestriction userRestriction = restrictionService.initCache(userId);
        //修改
        restrictionService.update(Chain.make("self_rate", selfRate).add("super_rate", superRate).add("disabled", "0"),
                Cnd.where("id", "=", userRestriction.getId()));
        //更新缓存数据
        restrictionService.saveCache(restrictionService.fetchByUserId(userId));
    }
}
